<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
    <title>
        Scene Layer with point geometries | Sample | ArcGIS API for JavaScript
        4.18
    </title>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        h1 {
            position: absolute;
            right: 20px;
            bottom: 20px;
            color: #3bd9db;
        }
    </style>
    <link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css"/>
    <script src="https://js.arcgis.com/4.18/"></script>
    <script>
        require([
            "esri/Map",
            "esri/views/SceneView",
            "esri/layers/SceneLayer",
            "esri/layers/FeatureLayer",
            "esri/tasks/support/Query",
            "esri/layers/WebTileLayer"
        ], function (Map, SceneView, SceneLayer, FeatureLayer, Query,WebTileLayer) {
            const renderer = {
                type: "unique-value", // autocasts as new UniqueValueRenderer()
                field: "OBJECTID",//匹配的字段
                defaultSymbol: {
                    type: "mesh-3d", // autocasts as new MeshSymbol3D()
                    symbolLayers: [
                        {
                            type: "fill", // autocasts as new FillSymbol3DLayer()
                            material: {
                                color: "#a1a3a6",
                                colorMixMode: "replace"
                            },
                            edges: {//在 3D 对象上设置轮廓边缘
                                type: "solid",
                                color: [0, 0, 0, 0.6],
                                size: 1
                            }
                        }
                    ]
                },
                //给不同楼层渲染颜色
                visualVariables: [//视觉变量
                    {
                        type: "color",//new ColorVariable
                        field: "Floor",//elevation_ft,name,objectid,type_airport
                        stops: [//定义用于在颜色视觉变量中创建连续颜色可视化的 色标。
                            {
                                value: 1,//指定要映射到给定颜色的数据值。
                                color: "#ece00f"
                            },
                            {
                                value: 2,//指定要映射到给定颜色的数据值。
                                color: "#45b97c"
                            },
                            {
                                value: 3,
                                color: "#ed1941"
                            },
                            {
                                value: 4,
                                color: "#375830"
                            },
                            {
                                value: 5,
                                color: "#ee03ff"
                            }
                        ]
                    }
                ],
                //给某一栋楼渲染颜色
                /*uniqueValueInfos: [//数组中的每个元素都是一个对象，提供有关与渲染器关联的唯一值的信息
                    {
                        value: "4469",//具有此值的要素将使用给定的符号进行渲染(匹配的值)
                        symbol: {
                            type: "mesh-3d",
                            symbolLayers: [
                                {
                                    type: "fill",
                                    material: {
                                        color: "#0046f5",
                                        colorMixMode: "replace"
                                    }
                                }
                            ]
                        }
                    }
                ],*/

            };
            const sceneLayer = new SceneLayer({
                url: "https://tiles.arcgis.com/tiles/U26uBjSD32d7xvm2/arcgis/rest/services/%E9%9D%92%E5%B2%9Bscene/SceneServer",
                renderer: renderer
            });

            //WebTileLayer 提供了一种将非 ArcGIS Server 地图切片作为图层添加到地图的简单方法
            var tiledLayer = new WebTileLayer({
                urlTemplate:"https://services3.arcgis.com/U26uBjSD32d7xvm2/arcgis/rest/services/%E4%B8%AD%E5%9B%BD%E5%8E%BF%E7%BA%A7%E8%A1%8C%E6%94%BF%E5%8C%BA%E5%88%92%E5%9B%BE%E5%B1%82/FeatureServer",
            });


            const map = new Map({
                layers: [sceneLayer],
                ground: {
                    opacity: 0.6,//地图背景的透明度
                    surfaceColor: "black",//地表的颜色
                    navigationConstraint: { //导航约束
                        type: "stay-above"//只能在地上
                    }
                },
            });

            const view = new SceneView({
                container: "viewDiv",
                map: map,
                zoom: 11,//缩放比,越小范围越大
                environment: {
                    starsEnabled: true,
                    atmosphereEnabled: false,//没有大气环境
                    background: {
                        type: "color",
                        color: "black"
                    }
                },
                spatialReference: {//坐标系
                    wkid: 4490
                }
            });

            //当加载完成之后开启动画效果
            view.when(() => {
                //将视角转给指定的目标
                view.goTo({
                    center: [120.34658084493894, 35.999908684467856],//初始化时地球默认的心中坐标
                }, {
                    animate: true,//动画效果
                    speedFactor: 2,//速度
                    duration: 10000,//持续时间
                    easing: "linear"//轨迹
                });

                //打印图层
                //console.log(sceneLayer);
            });

            //添加下拉框
            view.ui.add("esri-widget", "bottom-left");

            document
                .getElementById("floorSelect")
                .addEventListener("change", showFloors);

            //将按所选楼层过滤的功能
            function showFloors(event) {
                //检索存储在所选值中的查询
                var floorQuery = event.target.value;
                //用于过滤特征的 SQL where 子句。只有满足定义表达式的特征才会保留在客户端并显示在视图中。
                sceneLayer.definitionExpression = floorQuery;
            }

            var highlight;

            view.on("click", (event) => {
                //每次点击的时候应当把之前的高亮去除
                if(highlight){
                    highlight.remove();
                }

                //根据传入的屏幕坐标或者鼠标事件，获取地图图层在该点位下所有的展示的要素，
                view.hitTest(event).then((response) => {
                    console.log(response.results[0].graphic.attributes.OBJECTID);
                    //获取建筑物的唯一编码
                    let objectid = response.results[0].graphic.attributes.OBJECTID;

                    //根据楼的唯一编码查询
                    var queryExtent = new Query({
                        objectIds: [objectid],
                    });

                    //获取在给定图层的视图上创建的 LayerView
                    view.whenLayerView(sceneLayer).then((sceneLayerView)=>{
                        //查询出建筑物的详情信息,方便转场
                        sceneLayerView.queryExtent(queryExtent).then((result)=>{
                            //result就是建筑的详情信息
                            console.log(result);
                            view.goTo(result.extent.center, { speedFactor: 0.5 });
                        });

                        //高亮 突出显示,返回一个高亮处理程序，其中包含一个remove()
                        highlight = sceneLayerView.highlight(response.results[0].graphic);
                    });

                });
            });
        });
    </script>
</head>

<body>
<div id="viewDiv"></div>
<h1>青岛市楼层视觉显示</h1>
<div id="esri-widget" class="esri-widget">
    <select id="floorSelect">
        <!--注意Floor = 1 不能再单引号,因为Floor为Integer-->
        <option value="1=1">全部楼层</option>
        <option value="Floor = 1">1</option>
        <option value="Floor = 2">2</option>
        <option value="Floor = 3">3</option>
        <option value="Floor = 4">4</option>
        <option value="Floor > 5">5层以上</option>
    </select>
</div>
</body>
</html>
